﻿using System;
using System.Collections.Generic;
using System.IO.Compression;
using System.Linq;
using System.Runtime.Serialization.Formatters.Binary;
using System.Text;
using System.Threading.Tasks;
using GzipManagerPro.IO.Helpers;

namespace GzipManagerPro.IO
{
    partial class Archive
    {

        public static Archive FromFile(string path)
        {
            if (!System.IO.File.Exists(path))
                return null;

            System.IO.FileStream stream;
            stream = new System.IO.FileStream(path,
                System.IO.FileMode.Open,
                System.IO.FileAccess.Read,
                System.IO.FileShare.Read);

            byte[] buffer = new byte[4];
            int headerLength;

            // Step 1: Reading the last 4 bytes
            stream.Position = stream.Length - 4;
            stream.Read(buffer, 0, buffer.Length);
            headerLength = BitConverter.ToInt32(buffer, 0);


            // Step 2: Reading header contents
            buffer = new byte[headerLength];
            stream.Position = stream.Length - 4 - headerLength;
            stream.Read(buffer, 0, buffer.Length);
            stream.Close();
            // Step 3: Decompressing header contents
            buffer = buffer.FromGzip();

            // Step 4: Desrializing header
            Archive result = buffer.FromBinary<Archive>();
            result.FileName = path;
            return result;
        }

        public bool ExtractTo(string path)
        {
            return ExtractTo(path, null);
        }
        public bool ExtractTo(string path, string password)
        {
            this.CheckPassword(password);

            this.CurrentProgress = 0;
            this.TotalProgress = 1;
            // Step 1: Calculation
            OnArchiveMessage(new ArchiveMessageEventArgs(this.TotalProgress, this.CurrentProgress, "Starting extracting archive..."));
            this.TotalProgress = this.RootFolder.GetFilesCount();
            
            // Step 2: Extracting folders:
            bool result = this.RootFolder.ExtractTo(path, this, password);

            OnArchiveMessage(new ArchiveMessageEventArgs(this.TotalProgress, this.CurrentProgress, "Archive has been extracted successfully."));

            return result;
        }
    }
}
